﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataAccess;
using Entity;

namespace Controller
{
    public class VendorPOController:ControllerBase
    {
        public VendorPOController()
        {
        
        }
        public VendorPOController(SkyfabDataContextDataContext sdc)
        {
            Sdc = sdc;
        }

        public int addVendorPO(VendorPOEntity vendorPoEntity)
        {
            VendPO vendPo = TransformVendorPOEntityToVendPO(vendorPoEntity);
            Sdc.VendPOs.InsertOnSubmit(vendPo);
            Sdc.SubmitChanges();
            int vendorPOId = vendPo.Id;
            return vendorPOId;
        }

        public static VendPO TransformVendorPOEntityToVendPO(VendorPOEntity vendorPoEntity)
        {
            VendPO vendPo=new VendPO();
            vendPo.Address = vendorPoEntity.Address;
            vendPo.ApprovedBy = vendorPoEntity.ApprovedBy;
            vendPo.Attention = vendorPoEntity.Attention;
            vendPo.CreatedBy = vendorPoEntity.CreatedBy;
            vendPo.Date = vendorPoEntity.Date;
            vendPo.Fax = vendorPoEntity.Fax;
            vendPo.No = vendorPoEntity.No;
            vendPo.Phone = vendorPoEntity.Phone;
            vendPo.Reference = vendorPoEntity.Reference;
            vendPo.Remark = vendorPoEntity.Remark;
            vendPo.Status = vendorPoEntity.Status;
            vendPo.VendId = vendorPoEntity.VendId;
            vendPo.Type = vendorPoEntity.Type;
            vendPo.ZipCode = vendorPoEntity.ZipCode;
            vendPo.TotalQty = vendorPoEntity.TotalQty;
            return vendPo;
        }

        public IList<VendorPOEntity> findVendorPOByStatus(string status)
        {
            IList<VendPO> vendPos = (from v in Sdc.VendPOs
                                     where v.Status == status
                                     orderby v.Date descending ,v.Id descending 
                                     select v).ToList();
            IList<VendorPOEntity> vendorPoEntities= new List<VendorPOEntity>();
            foreach (VendPO vendPo in vendPos)
            {
                VendorPOEntity vendorPoEntity = TransformVendorPOToVendorPOEntity(vendPo);
                vendorPoEntities.Add(vendorPoEntity);
            }
            return vendorPoEntities;
        }

        public IList<VendorPOEntity> findVendorPOByVendorIdAndStatus(int vendorId, string status)
        {
            IList<VendorPOEntity> vendorPoEntities = this.findVendorPOByStatus(status);
            vendorPoEntities = (from vendorPoEntity in vendorPoEntities
                                where vendorPoEntity.VendId == vendorId
                                orderby vendorPoEntity.Date descending, vendorPoEntity.Id descending 
                                select vendorPoEntity).ToList();
            return vendorPoEntities;
        }
       public IList<VendorPOEntity> findVendorPOByVendor(int vendorId)
        {
           List<VendPO> vendPos = (from v in Sdc.VendPOs
                                   where v.VendId == vendorId && (v.Status=="new" || v.Status=="ongoing")
                                   orderby v.No ascending
                                   select v).ToList();
           IList<VendorPOEntity> vendorPoEntities = new List<VendorPOEntity>();
           foreach (VendPO vendPo in vendPos)
           {
               VendorPOEntity vendorPoEntity = TransformVendorPOToVendorPOEntity(vendPo);
               vendorPoEntities.Add(vendorPoEntity);
           }
           return vendorPoEntities;
        }


        public VendorPOEntity findVendorPOById(int vendorPOId)
        {
            VendPO vendPo = (from v in Sdc.VendPOs
                             where v.Id == vendorPOId
                             select v).SingleOrDefault();
            VendorPOEntity vendorPoEntity=TransformVendorPOToVendorPOEntity(vendPo);

            return vendorPoEntity;

        }

        public static decimal CountTotalAmount(VendPO vendPo)
        {
            IList<VendPOItem> vendPoItems = vendPo.VendPOItems.ToList();
            decimal totalAmount = 0;
            for (int i = 0; i < vendPoItems.Count; i++)
            {
                totalAmount = totalAmount + (vendPoItems.ElementAt(i).Price * vendPoItems.ElementAt(i).RequestQty);
            }
            return totalAmount;
        }

        public static VendorPOEntity TransformVendorPOToVendorPOEntity(VendPO vendPo)
        {
            VendorPOEntity vendorPoEntity=new VendorPOEntity();
            vendorPoEntity.Id = vendPo.Id;
            vendorPoEntity.No = vendPo.No;
            vendorPoEntity.VendId = vendPo.VendId;
            vendorPoEntity.Type = vendPo.Type;
            vendorPoEntity.Address = vendPo.Address;
            vendorPoEntity.Attention = vendPo.Attention;
            vendorPoEntity.VendorShortName = vendPo.Vendor.ShortName;
            vendorPoEntity.Date = vendPo.Date;
            vendorPoEntity.CreatedBy = vendPo.CreatedBy;
            vendorPoEntity.ApprovedBy = vendPo.ApprovedBy;
            vendorPoEntity.Status = vendPo.Status;
            vendorPoEntity.ZipCode = vendPo.ZipCode;
            vendorPoEntity.Phone = vendPo.Phone;
            vendorPoEntity.Fax = vendPo.Fax;
            vendorPoEntity.Reference = vendPo.Reference;
            vendorPoEntity.Remark = vendPo.Remark;
            vendorPoEntity.Amount = CountTotalAmount(vendPo);
            vendorPoEntity.TotalQty = vendPo.TotalQty;

            if(vendPo.Type == "purchase" || vendPo.TotalQty==0)
            {
                vendorPoEntity.TotalOpenQty = vendPo.VendPOItems.Sum(p => p.RequestQty) - vendPo.VendPOItems.Sum(p => p.CompleteQty);    
            }
            else
            {
                vendorPoEntity.TotalOpenQty = vendPo.TotalQty - vendPo.VendPOItems.Sum(p => p.CompleteQty);
            }
            
            return vendorPoEntity;
        }



        public void updateVendorPOStatus(int vendPOId,string status)
        {
            VendPO vendPo = (from v in Sdc.VendPOs
                             where v.Id == vendPOId
                             select v).SingleOrDefault();
            vendPo.Status = status;
            Sdc.SubmitChanges();

        }

        public int FindLargestVendorPoNumber()
        {
            SettingController settingController = new SettingController();

            int largestVendorPONO = settingController.findLargestVendorPONO();

            return largestVendorPONO;
        }

        public void DeleteVendorPOById(int vendPOId)
        {
            //Delete the po item first, otherwise will cause the FK conflict
            VendorPOItemController vendorPoItemController=new VendorPOItemController();
            vendorPoItemController.DeleteVendorPOItemByVendorPOId(vendPOId);
            
            VendPO vendPo = (from v in Sdc.VendPOs
                             where v.Id == vendPOId
                             select v).SingleOrDefault();
            Sdc.VendPOs.DeleteOnSubmit(vendPo);
            Sdc.SubmitChanges();
            
        }


        public void UpateVendorPO(VendorPOEntity vendorPoEntity)
        {
            VendPO vendPo = (from v in Sdc.VendPOs
                             where v.Id == vendorPoEntity.Id
                             select v).SingleOrDefault();
            vendPo.No=vendorPoEntity.No;
            vendPo.VendId=vendorPoEntity.VendId;
            vendPo.Phone=vendorPoEntity.Phone;
            vendPo.Reference=vendorPoEntity.Reference;
            vendPo.Remark=vendorPoEntity.Remark;
            vendPo.ZipCode=vendorPoEntity.ZipCode;
            vendPo.Address=vendorPoEntity.Address;
            vendPo.ApprovedBy=vendorPoEntity.ApprovedBy;
            vendPo.CreatedBy=vendorPoEntity.CreatedBy;
            vendPo.Attention=vendorPoEntity.Attention;
            vendPo.Fax=vendorPoEntity.Fax;
            Sdc.SubmitChanges();
        }



        public IList<VendorPOEntity> FindAllVendorPO()
        {
            IList<VendPO> vendPos = (from v in Sdc.VendPOs
                                     orderby v.Date descending ,v.Id descending 
                                     select v).ToList();
            IList<VendorPOEntity> vendorPoEntities=new List<VendorPOEntity>();
            foreach (var vendorPo in vendPos)
            {
                VendorPOEntity vendorPoEntity = TransformVendorPOToVendorPOEntity(vendorPo);
                vendorPoEntities.Add(vendorPoEntity);
            }
            return vendorPoEntities;
        }

        public IList<VendorPOEntity> FindVendorPOByNo(string poNo)
        {
            IList<VendPO> vendPos = (from v in Sdc.VendPOs
                                     where v.No.Contains(poNo)
                                     orderby v.Date descending, v.Id descending
                                     select v).ToList();
            IList<VendorPOEntity> vendorPoEntities = new List<VendorPOEntity>();
            foreach (var vendorPo in vendPos)
            {
                VendorPOEntity vendorPoEntity = TransformVendorPOToVendorPOEntity(vendorPo);
                vendorPoEntities.Add(vendorPoEntity);
            }
            return vendorPoEntities;
        }

        public IList<VendorPOEntity> FindVendorPOByDate(DateTime fromDate, DateTime toDate)
        {
            IList<VendPO> VendorPos = (from v in Sdc.VendPOs
                                         where v.Date >= fromDate && v.Date <= toDate
                                       orderby v.Date descending, v.Id descending
                                         select v).ToList();
            IList<VendorPOEntity> VendorPoEntities = new List<VendorPOEntity>();
            foreach (var vendPo in VendorPos)
            {
                VendorPOEntity VendorPoEntity = TransformVendorPOToVendorPOEntity(vendPo);
                VendorPoEntities.Add(VendorPoEntity);
            }
            return VendorPoEntities;
        }

        public bool CheckCustomerPONoAvailability(string newPONo, ref string msg)
        {
            bool result = true;
            var count = (from v in Sdc.VendPOs
                         where v.No.ToUpper() == newPONo.ToUpper()
                         select v).Count();
            if (count > 0)
            {
                msg = "PO NO. already existed!";
                return false;

            }
            else
            {
                return true;
            }
            
        }
    }
}
